package manager.rank;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


import org.springframework.beans.BeansException;

import com.fasterxml.jackson.core.JsonProcessingException;

import database.DBService;
import database.pojo.SingleSongScoreInfo;
import database.pojo.UserInfo;
import io.netty.channel.ChannelFuture;
import manager.connection.ClientConnectionManager;
import manager.player.basic.type.BasicPlayerInfo;
import manager.rank.type.PlayerRankInfo;
import manager.rank.type.RankType;
import manager.rank.type.singSongNumInfo;
import net.socket.server.protocal.PROTOID;
import net.socket.server.request.GetRankListRequest;
import net.socket.server.request.IRequest;
import net.socket.server.response.GetRankListResponse;
import observable.subject.MessageCenter;

import util.MyFactory;
import util.ResultTypeList;

public class ManagerRank{
	
private ClientConnectionManager ccm = null;

	
	
	public void init() {
		MessageCenter mc = MyFactory.context.getBean("MessageCenter", MessageCenter.class);
		mc.register(PROTOID.GET_RANK_LIST_REQ, (int cmd, IRequest request)->getRankList(cmd, request));
		
		
		ccm = MyFactory.context.getBean("ClientConnectionManager", ClientConnectionManager.class);
		
	}


	private int getRankList(int cmd, IRequest request) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException, BeansException, SQLException {
		GetRankListRequest req =(GetRankListRequest)request;
		GetRankListResponse rsp = new GetRankListResponse();
		if("".equals(req.getOpenId())) {
			rsp.setResult(ResultTypeList.NULL_ARGS);
			ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
			return ResultTypeList.NULL_ARGS;
		}
		
		ChannelFuture cf = null;
		if (req.getRankType()== RankType.SingleSongScoreRank) {
			return getSingleSongScoreRank(req);
		}else if(req.getRankType() ==RankType.SongNumRank) {
			return getSongNumRank(req);
		}else if(req.getRankType() ==RankType.SingTimesRank) {
			return getSingTimesRank(req);
		}else if(req.getRankType() ==RankType.TotalChargeRank) {
			return getTotalChargeRank(req);
		}else if(req.getRankType() ==RankType.TotalTimeRank) {
			return getTotalTimeRank(req);
		}else if(req.getRankType() ==RankType.TotalConsumeRank) {
			return getTotalConsumeRank(req);
		}else if(req.getRankType() ==RankType.DailyChargeRank) {
			return getDailyChargeRank(req);
		}else if(req.getRankType() ==RankType.DailyConsumeRank) {
			return getDailyConsumeRank(req);
		}else if(req.getRankType() ==RankType.DailyTimeRank) {
			return getDailyTimeRank(req);
		}else if(req.getRankType() ==RankType.MachineNumRank) {
			return getMachineNumRank(req);
		}else if(req.getRankType() ==RankType.WinRank) {
				return getWinRank(req);
		}else {
			rsp.setResult(ResultTypeList.ERROR_ARGS);
			cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
			if(cf == null) {
				return ResultTypeList.NO_CONNECTION_FOUND;
			}else {
				return ResultTypeList.SUCCESS;
			}
		}
	}


	private int getWinRank(GetRankListRequest req) throws BeansException, SQLException, IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		int rankRange ;
		if(req.getRankRange() == 0) {
			rankRange =0;
		}else {
			rankRange =req.getMachineId();
		}
		
		List<PlayerRankInfo> playerRankInfoList = new ArrayList<PlayerRankInfo>();
		int selfRank =MyFactory.context.getBean("DBService", DBService.class).getTotalRank(rankRange,req.getNumber(),playerRankInfoList,req.getOpenId(),RankType.WinRank);
		PlayerRankInfo selfPlayerInfo=new PlayerRankInfo();
		if(selfRank!=0) {
			selfPlayerInfo=playerRankInfoList.get(selfRank-1);
		}else {
			selfPlayerInfo =MyFactory.context.getBean("DBService", DBService.class).getTotal(rankRange,req.getOpenId(),RankType.WinRank);
		}
		
		rsp.setNumber(playerRankInfoList.size());
		rsp.setPlayerRankInfoList(playerRankInfoList);
		rsp.setSelfPlayerInfo(selfPlayerInfo);
		rsp.setRankType(RankType.WinRank);
		rsp.setResult(ResultTypeList.SUCCESS);
		//rsp.setTotalNum(totalNum);
		ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		return ResultTypeList.SUCCESS;
	}


	private int getMachineNumRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		ChannelFuture cf =null;
		
		cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}


	private int getDailyTimeRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		ChannelFuture cf =null;
		
		cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}


	private int getDailyConsumeRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		ChannelFuture cf =null;
		
		cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}


	private int getDailyChargeRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		ChannelFuture cf =null;
		
		cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}


	private int getTotalConsumeRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		ChannelFuture cf =null;
		
		cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}


	private int getTotalTimeRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();
		ChannelFuture cf =null;
		
		cf = ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		if(cf == null) {
			return ResultTypeList.NO_CONNECTION_FOUND;
		}else {
			return ResultTypeList.SUCCESS;
		}
	}


	private int getTotalChargeRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException, BeansException, SQLException {
		GetRankListResponse rsp = new GetRankListResponse();
		int rankRange ;
		if(req.getRankRange() == 0) {
			rankRange =0;
		}else {
			rankRange =req.getMachineId();
		}
		
		List<PlayerRankInfo> playerRankInfoList = new ArrayList<PlayerRankInfo>();
		int selfRank =MyFactory.context.getBean("DBService", DBService.class).
				getTotalRank(rankRange,req.getNumber(),playerRankInfoList,req.getOpenId(),RankType.DailyChargeRank);
		PlayerRankInfo selfPlayerInfo=new PlayerRankInfo();
		if(selfRank!=0) {
			selfPlayerInfo=playerRankInfoList.get(selfRank-1);
		}else {
			selfPlayerInfo =MyFactory.context.getBean("DBService", DBService.class).getTotal(rankRange,req.getOpenId(),RankType.DailyChargeRank);
		}
		
		rsp.setNumber(playerRankInfoList.size());
		rsp.setPlayerRankInfoList(playerRankInfoList);
		rsp.setSelfPlayerInfo(selfPlayerInfo);
		rsp.setRankType(RankType.TotalChargeRank);
		rsp.setResult(ResultTypeList.SUCCESS);
		//rsp.setTotalNum(totalNum);
		ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		return ResultTypeList.SUCCESS;
		
		
	}


	private int getSingTimesRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException {
		GetRankListResponse rsp = new GetRankListResponse();

		
		ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		return ResultTypeList.SUCCESS;
	}


	private int getSongNumRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException{
		GetRankListResponse rsp = new GetRankListResponse();
		String openId = null;
		int number = req.getNumber();
		int rankRange ;
		if(req.getRankRange() == 0) {
			rankRange =0;
		}else {
			rankRange =req.getMachineId();
		}
		List<PlayerRankInfo> playerRankInfoList = new ArrayList<PlayerRankInfo>();
		PlayerRankInfo pInfo = null;
		PlayerRankInfo selfPlayerInfo =new PlayerRankInfo();
		
		BasicPlayerInfo bPinfo = null;
		BasicPlayerInfo selfBPinfo =new BasicPlayerInfo();
		
		UserInfo userInfo = null;
		ArrayList<singSongNumInfo> singSongNumList = null;
		
		int isInRank =0;//记录这个人是否在排行榜里面
		singSongNumList = MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class)
				.getSingSongNumRankList(req.getOpenId(), number, rankRange);
				
		//singSongNumList =MyFactory.context.getBean("SingleSongScoreDBServer",SingleSongScoreDBServer.class).getsingSongNumList( number, rankRange);
		for(int i =0 ;i<singSongNumList.size();i++) {
			pInfo = new PlayerRankInfo();
			bPinfo = new BasicPlayerInfo();
			userInfo = new UserInfo();
			
			//玩家基本信息
			openId= singSongNumList.get(i).getOpenId();
			userInfo =MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId(openId) ;
			
			if(openId.equals(req.getOpenId())) {
				isInRank=1;
				selfBPinfo = getBPInfoNoScoreAndRank(userInfo,openId);
				selfPlayerInfo.setRank(singSongNumList.get(i).getRank());
				selfPlayerInfo.setRankValue(singSongNumList.get(i).getNumber());
				selfPlayerInfo.setPlayerInfo(selfBPinfo);
				
				rsp.setSelfPlayerInfo(selfPlayerInfo);
			}
			
			bPinfo =getBPInfoNoScoreAndRank(userInfo,openId);

			pInfo.setRank(singSongNumList.get(i).getRank());//唱歌次数的排名
			pInfo.setRankValue(singSongNumList.get(i).getNumber());//唱了多少次
			pInfo.setPlayerInfo(bPinfo);
			
			playerRankInfoList.add(pInfo);
			
		}
		
		if(isInRank == 0) {
			userInfo =MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId(req.getOpenId()) ;
			selfBPinfo = getBPInfoNoScoreAndRank(userInfo,openId);
			Map<Integer, Integer> rankMap=MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class)
					.getSingSongNumRankForPeople(req.getOpenId(),rankRange);
			for(Integer rank:rankMap.keySet()) {
				//selfPlayerInfo.setRank(rank);
				selfPlayerInfo.setRank(0);//不在榜上先按0处理
				selfPlayerInfo.setRankValue(rankMap.get(rank));
			}
			selfPlayerInfo.setPlayerInfo(selfBPinfo);
			
			rsp.setSelfPlayerInfo(selfPlayerInfo);
		}
		
		rsp.setTotalNum(MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class)
				.getTotalNumOfOpenId(rankRange));
		rsp.setNumber(singSongNumList.size());
		//rsp.setRankParam(songId);
		rsp.setRankType(RankType.SongNumRank);
		rsp.setPlayerRankInfoList(playerRankInfoList);
		rsp.setResult(ResultTypeList.SUCCESS);
		
		
		ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		return ResultTypeList.SUCCESS;

	}


	private int getSingleSongScoreRank(GetRankListRequest req) throws IllegalArgumentException, IllegalAccessException, JsonProcessingException{
		GetRankListResponse rsp = new GetRankListResponse();
		String songId = req.getRankParam();
		String openId = null;
		int number = req.getNumber();
		int rankRange ;
		if(req.getRankRange() == 0) {
			rankRange =0;
		}else {
			rankRange =req.getMachineId();
		}
		
		List<PlayerRankInfo> playerRankInfoList = new ArrayList<PlayerRankInfo>();
		PlayerRankInfo pInfo = null;
		PlayerRankInfo selfPlayerInfo =new PlayerRankInfo();
		
		BasicPlayerInfo bPinfo = null;
		BasicPlayerInfo selfBPinfo =new BasicPlayerInfo();
		UserInfo userInfo = null;
		ArrayList<SingleSongScoreInfo> scoreList = null;
		int isInRank =0;//记录这个人是否在排行榜里面
		
		scoreList = MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class)
				.getSingleSongScoreRankInfo(songId, number, rankRange);
		System.out.println("getSingleSongScoreRank----scoreList.size---"+scoreList.size());
		for(int i =0 ;i<scoreList.size();i++) {
			pInfo = new PlayerRankInfo();
			bPinfo = new BasicPlayerInfo();
			userInfo = new UserInfo();
			
			//查询获得这个分数的玩家信息
			openId= scoreList.get(i).getOpenId();
			userInfo =MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId(openId);
			if(openId.equals(req.getOpenId())) {
				isInRank=1;
				selfBPinfo = getBPInfoNoScoreAndRank(userInfo,openId);
				selfPlayerInfo.setRank(scoreList.get(i).getRank());
				selfPlayerInfo.setRankValue(scoreList.get(i).getScore());
				selfPlayerInfo.setPlayerInfo(selfBPinfo);
				
				rsp.setSelfPlayerInfo(selfPlayerInfo);
			}
			bPinfo =getBPInfoNoScoreAndRank(userInfo, openId);
			pInfo.setRank(scoreList.get(i).getRank());
			pInfo.setRankValue(scoreList.get(i).getScore());
			pInfo.setPlayerInfo(bPinfo);
			
			playerRankInfoList.add(pInfo);
			
		}
		
		if(isInRank == 0) {
			userInfo =MyFactory.context.getBean("DBService", DBService.class).selectUserInfoByOpenId(req.getOpenId()) ;
			
			selfBPinfo =getBPInfoNoScoreAndRank(userInfo, req.getOpenId());
			Map<Integer, Integer> rankMap=MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class)
					.getSingleSongScoreRankForTheOpenId(req.getOpenId(),songId,rankRange);
			for(Integer rank:rankMap.keySet()) {
				selfPlayerInfo.setRank(rank);
				selfPlayerInfo.setRankValue(rankMap.get(rank));
			}
			selfPlayerInfo.setPlayerInfo(selfBPinfo);
			
			rsp.setSelfPlayerInfo(selfPlayerInfo);
		}
		rsp.setTotalNum(MyFactory.context.getBean("QuireRankOfSong", QuireRankOfSong.class)
				.getTotalNumOfSongId(songId,rankRange));
		rsp.setNumber(scoreList.size());
		rsp.setRankParam(songId);
		rsp.setRankType(RankType.SingleSongScoreRank);
		rsp.setPlayerRankInfoList(playerRankInfoList);
		rsp.setResult(ResultTypeList.SUCCESS);
		
		ccm.sendResponse(PROTOID.GET_RANK_LIST_RSP, req.getMachineId(), rsp);
		return ResultTypeList.SUCCESS;
		
	}


	private BasicPlayerInfo getBPInfoNoScoreAndRank(UserInfo userInfo, String openId) {
		if(userInfo ==null)
			return null;
		BasicPlayerInfo selfBPinfo =new BasicPlayerInfo();
		selfBPinfo.setHeadImgURL(userInfo.getHeadImgUrl());
		selfBPinfo.setLvl(userInfo.getLvl());
		selfBPinfo.setNickName(userInfo.getNickName());
		selfBPinfo.setAvatarId(userInfo.getAvatarId());
		selfBPinfo.setOpenId(openId);
		selfBPinfo.setVipGrade(userInfo.getVipGrade());
		return selfBPinfo;
		
	}


	
	
}